//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package org.tuiofx.internal.gesture;

import javafx.application.Platform;
import javafx.scene.Node;
import javafx.scene.input.PickResult;
import javafx.scene.input.RotateEvent;
import org.tuiofx.Configuration;
import org.tuiofx.internal.util.LogUtils;

public class RotateGestureRecognizer extends GestureRecognizer {
    private boolean isRotating = false;
    private RotationData rotationData;
    private double startRotation = 0.001;
    private final double minRotation = 0.0015;
    private double totalAngle = 0.0;

    public RotateGestureRecognizer(Node targetNode, Configuration config) {
        super(targetNode, config);
        this.requiredNumberOfTouches = 2;
        this.rotationData = new RotationData(0.0, 0.0);
    }

    public void touchesBegan(TuioTouchPoint touchPoint) {
        if (this.getTargetNode() != null && this.touchPointsCount == this.requiredNumberOfTouches) {
            if (!this.isRotating) {
                double initialAngle = this.getAngle();
                this.rotationData.setPrevAngle(initialAngle);
                this.rotationData.setCurAngle(initialAngle);
            }

        }
    }

    public void touchesMove(final TuioTouchPoint touchPoint) {
        if (this.getTargetNode() != null && this.touchPointsCount == this.requiredNumberOfTouches) {
            TuioTouchPoint firstTouchPoint = this.touchPointsList.get(0);
            TuioTouchPoint secondTouchPoint = this.touchPointsList.get(1);
            if (!touchPoint.equals(firstTouchPoint) && !touchPoint.equals(secondTouchPoint)) {
                LogUtils.debug("THIS TOUCH POINT " + touchPoint.getId() + " IS IRRELEVANT TO ROTATION");
            } else {
                double currentAngle = this.getAngle();
                double deltaAngle = currentAngle - this.rotationData.getPrevAngle();
                if (!this.isRotating && Math.abs(deltaAngle) > this.startRotation) {
                    Platform.runLater(new Runnable() {
                        public void run() {
                            PickResult pickResult = new PickResult(touchPoint.getTargetNode(), touchPoint.getSceneX(), touchPoint.getSceneY());
                            RotateGestureRecognizer.this.fireEvent(touchPoint.getTargetNode(), new RotateEvent(RotateEvent.ROTATION_STARTED, touchPoint.getSceneX(), touchPoint.getSceneY(), touchPoint.getScreenX(), touchPoint.getScreenY(), false, false, false, false, true, false, 0.0, 0.0, pickResult));
                        }
                    });
                }

                if (Math.abs(deltaAngle) > minRotation) {
                    this.rotationData.setPrevAngle(this.rotationData.getCurAngle());
                    this.rotationData.setCurAngle(currentAngle);
                    this.isRotating = true;
                    final double x = this.getCentroid().getX();
                    final double y = this.getCentroid().getY();
                    final double screenX = touchPoint.getScreenX();
                    final double screenY = touchPoint.getScreenY();
                    final boolean _shiftDown = false;
                    final boolean _controlDown = false;
                    final boolean _altDown = false;
                    final boolean _metaDown = false;
                    final boolean _direct = true;
                    final boolean _inertia = false;
                    final double currentDeltaAngle = Math.toDegrees(deltaAngle);
                    this.totalAngle += currentDeltaAngle;
                    Platform.runLater(new Runnable() {
                        public void run() {
                            PickResult pickResult = new PickResult(touchPoint.getTargetNode(), touchPoint.getSceneX(), touchPoint.getSceneY());
                            RotateGestureRecognizer.this.fireEvent(touchPoint.getTargetNode(), new RotateEvent(RotateEvent.ROTATE, x, y, screenX, screenY, _shiftDown, _controlDown, _altDown, _metaDown, _direct, _inertia, currentDeltaAngle, RotateGestureRecognizer.this.totalAngle, pickResult));
                        }
                    });
                }

            }
        }
    }

    public void touchesEnd(final TuioTouchPoint touchPoint) {
        if (this.touchPointsList.size() <= 1) {
            if (this.touchPointsList.size() == 1 && this.isRotating) {
                this.isRotating = false;
                final PickResult pickResult = new PickResult(touchPoint.getTargetNode(), touchPoint.getSceneX(), touchPoint.getSceneY());
                Platform.runLater(new Runnable() {
                    public void run() {
                        RotateGestureRecognizer.this.fireEvent(touchPoint.getTargetNode(), new RotateEvent(RotateEvent.ROTATION_FINISHED, touchPoint.getSceneX(), touchPoint.getSceneY(), touchPoint.getScreenX(), touchPoint.getScreenY(), false, false, false, false, true, false, 0.0, RotateGestureRecognizer.this.totalAngle, pickResult));
                    }
                });
                this.totalAngle = 0.0;
            }

        }
    }

    private double getAngle() {
        if (this.touchPointsList.size() >= 2) {
            double deltaX = this.touchPointsList.get(1).getSceneX() - this.touchPointsList.get(0).getSceneX();
            double deltaY = this.touchPointsList.get(1).getSceneY() - this.touchPointsList.get(0).getSceneY();
            return Math.atan2(deltaY, deltaX);
        } else {
            LogUtils.debug("Failed to calculate the rotation angle");
            return 0.0;
        }
    }

    private static class RotationData {
        private double prevAngle;
        private double curAngle;

        public RotationData(double prevAngle, double curAngle) {
            this.prevAngle = prevAngle;
            this.curAngle = curAngle;
        }

        public double getPrevAngle() {
            return this.prevAngle;
        }

        public void setPrevAngle(double prevAngle) {
            this.prevAngle = prevAngle;
        }

        public double getCurAngle() {
            return this.curAngle;
        }

        public void setCurAngle(double curAngle) {
            this.curAngle = curAngle;
        }
    }
}
